<!--
 * @Author: 宋绍华
 * @Date: 2024-11-06 17:35:01
 * @LastEditors: 宋绍华
 * @LastEditTime: 2025-01-15 11:00:58
 * @FilePath: \sr_system_manager_ui\src\views\project\manage\index.vue
 * @Description: 项目管理
-->
<template>
	<div class="app-container home">
		<div>
			<SearchBar ref="searchBarRef" v-if="showSearch" :hideRightArea="false"
				:components="projectNature !== projectNatureEnum.projectNatureHorizontal ? conditionComponents : conditionComponents2"
				@search="onSearch" />
			<div class="bg-#f7f8fa h-16px w-140% ml-[-20px] mt-16px"></div>
			<TableForm :right-first-btn-permission="[`${perMissMainStr}:export`]" :auto-height="true" :data="configList"
				:columns="columnsCom" :pageSize="20" :tableLoading="loading" :total-count="total"
				v-model:showSearch="showSearch" :show-pagination="true" :showRowSelection="true" btnTitle="发布申报通知"
				:hideLeftMenu="false" :showToolBar="true" :download="(params) => { exportListData(params) }"
				@select-rows="onSelectRows" @refresh="refreshTableData">
				<template #leftMenu="">
					<div>
						<el-button v-if="projectNature === projectNatureEnum.projectNaturePortrait"
							@click="linkToCreate(projectNature)" v-hasPermi="['project:portrait:portraitManage:application']"
							type="primary">纵向项目申报</el-button>
						<el-button v-hasPermi="['project:school:schoolManage:application']"
							v-if="projectNature === projectNatureEnum.projectNatureSchool" @click="linkToCreate(projectNature)"
							type="primary">校级项目申报</el-button>
						<el-button @click="setAlert" v-hasPermi="[`${perMissMainStr}:warning`]" type="primary">预警设置</el-button>
					</div>
				</template>
				<template #createTime="{ record, rowIndex }">
					<div v-if="record.approvalTime && record.conclusionTime">
						<span>{{ formateDate(record.approvalTime).format('YYYY-MM-DD') }} ~ {{
							formateDate(record.conclusionTime).format('YYYY-MM-DD') }}</span>
					</div>
					<span v-else>-</span>
				</template>
				<template #statusName="{ record }">
					<div class="flex items-center space-x-[8px]">
						<span class="h-[6px] w-[6px] rounded-[3px]"
							:style="{ backgroundColor: intermediateInspectionStatusBgColorMap[record.status as keyof typeof intermediateInspectionStatusBgColorMap] }" />
						<span
							:style="{ color: intermediateInspectionStatusBgColorMap[record.status as keyof typeof intermediateInspectionStatusBgColorMap] }">{{
								record.statusName }}</span>
					</div>
				</template>
				<template #default="{ record }">
					<div class="flex flex-wrap">
						<BtnRender role="ADMIN" @update="refreshTableData(queryParams)" :record="record"
							:projectNature="projectNature" :status="record.status" />
					</div>
				</template>
			</TableForm>
			<!-- 添加或修改参数配置对话框 -->
			<el-dialog :title="title" v-model="open" width="700px" append-to-body>
				<div>
					<!-- 横向不需要展示这个 -->
					<div v-if="projectNature !== projectNatureEnum.projectNatureHorizontal" class="flex items-center">
						<el-checkbox style="width: 120px" v-model="checkFlag" label="中检提交预警" size="large" />
						<span mr-10px ml-10px inline-block>中检开始后</span>
						<el-input-number :controls='false' :precision="0" :disabled="!checkFlag" v-model="checkNumber" mr-10px
							style="width: 200px" placeholder="请输入" />
						<el-select :disabled="!checkFlag" v-model="checkUnit" ml-10px style="width: 200px">
							<el-option :value="1" label="天"></el-option>
							<el-option :value="2" label="月"></el-option>
							<el-option :value="3" label="年"></el-option>
						</el-select>
					</div>
					<div class="flex items-center mt-20px">
						<el-checkbox style="width: 120px" v-model="conclusionFlag" mr-10px label="结项预警" size="large" />
						<span mr-10px ml-10px inline-block>预计结项前</span>
						<el-input-number :controls='false' :precision="0" :disabled="!conclusionFlag" v-model="conclusionNumber"
							mr-10px style="width: 200px" placeholder="请输入" />
						<el-select :disabled="!conclusionFlag" v-model="conclusionUnit" ml-10px style="width: 200px">
							<el-option :value="1" label="天"></el-option>
							<el-option :value="2" label="月"></el-option>
							<el-option :value="3" label="年"></el-option>
						</el-select>
					</div>
				</div>
				<template #footer>
					<div class="dialog-footer">
						<el-button @click="cancel">取 消</el-button>
						<el-button type="primary" @click="submitForm">确 定</el-button>
					</div>
				</template>
			</el-dialog>
		</div>

		<ConfirmProject v-model:visible="projectDialogVisible" v-if="projectDialogVisible" />

		<!-- 日志 -->
		<AuditRecordDrawer v-model:visible="auditRecordVisible" :project-id="curPid" v-if="auditRecordVisible" />
	</div>
</template>

<script lang="tsx">
export default defineComponent({
	beforeRouteEnter(to, from, next) {
		const nature = Number(to.query.projectNature || 1)
		if (nature === 2) {
			to.meta.title = '校级项目列表';
		} else if (nature === 1) {
			to.meta.title = '纵向项目列表';
		} else {
			to.meta.title = '横向项目列表';
		}
		next()
	}
})

</script>

<script setup name="Index" lang="tsx">
import { ElMessage } from 'element-plus'
import ConfirmProject from '../components/ConfirmProject/index.vue'
import { getProjectPageApi, getDicListApi, warningBaseCreateApi, getAlertDetailApi, warningBaseUpdateApi, exportProjectListApi } from '@/api/project'
import formateDate from '@/utils/formateDate'
import { projectNatureEnum, } from '@/utils/constEnum'
import AuditRecordDrawer from '@/components/AuditRecordDrawer/index.vue'
import { projectStatusList } from '@/utils/constText'
import { getDicListById } from '../utils'
import { BaseSuccessRespDTO, ProjectWarmingBaseDetailVO } from '@/api/project/types'
import BtnRender from '../components/MyProject/BtnRender.vue'
import { intermediateInspectionStatusBgColorMap } from '@/utils/constText';
import { getDepartmentListReq } from '@/api/system/user'
import { DepartmentPageVO } from '@/api/system/user/type'
import { downloadFile } from '@/utils/download'

const route = useRoute()
const router = useRouter()
const projectDialogVisible = ref(false);
const typeList = ref([]) // 项目状态list
const projectTypeList = ref([]) // 项目分类list
const departmentList = ref<DepartmentPageVO[]>([]) // 所属院系（部）list
const projectLevelList = ref([]) // 项目级别list
const auditRecordVisible = ref(false)
const selectRowList = ref<string[]>([])
const curPid = ref('') // 当前项目id
const status = computed<number[]>(() => {
	return route.query.status ? JSON.parse(route.query.status as string) : undefined
})

const projectType = computed<number[]>(() => {
	return route.query.projectType || undefined
})
const searchBarRef = ref()
const projectNature = computed(() => {
	return Number(route.query.projectNature)
})

const columnsCom = computed(() => {
	return projectNature.value === projectNatureEnum.projectNatureHorizontal ? columns2.value : columns.value
})

// 权限字符串
const perMissMainStr = computed(() => {
	switch (projectNature.value) {
		case projectNatureEnum.projectNatureSchool:
			return ['project:school:schoolManage']
		case projectNatureEnum.projectNatureHorizontal:
			return ['project:horizontalManage:horizontalManage']
		default:
			return ['project:portrait:portraitManage']
	}
})

// 获取学院/部列表
const { run: getDepartmentList } = useRequest(getDepartmentListReq, {
	manual: true,
	onSuccess: (res: DepartmentPageVO[]) => {
		res?.forEach((item) => {
			item.title = item.departmentName
			item.value = item.departmentId
		})
		departmentList.value = res
	}
})

// 获取相关字典
const { run: getDicList } = useRequest(getDicListApi, {
	manual: true,
	onSuccess: (res) => {
		// 类别
		typeList.value = getDicListById(projectNature.value === projectNatureEnum.projectNatureHorizontal ? 12 : 7, res, true)
		// 项目分类
		projectTypeList.value = getDicListById(projectNature.value === projectNatureEnum.projectNatureHorizontal ? 6 : projectNature.value === projectNatureEnum.projectNatureSchool ? 27 : 5, res, true)
		// 项目级别
		projectLevelList.value = getDicListById(18, res, true)
	}
})

// 表头
const columns = ref([
	{
		title: '序号',
		width: 48,
		dataIndex: 'key',
		formatter: (_row: any, _column: any, _cellValue: any, index: number) => {
			return index + 1
		}
	},
	{
		title: '项目编号',
		dataIndex: 'projectCode',
		slotName: 'projectCode',
		minWidth: 100,
	},
	{
		title: '项目名称',
		minWidth: 330,
		dataIndex: 'projectName',
		slotName: 'projectName',
	},
	{
		title: '负责人',
		minWidth: 80,
		dataIndex: 'managerName',
		slotName: 'managerName',
		tooltip: true,
	},
	{
		title: '团队成员',
		minWidth: 100,
		dataIndex: 'teamMember',
		slotName: 'teamMember',
		tooltip: true,
	},
	{
		title: '项目分类',
		minWidth: 120,
		dataIndex: 'projectTypeName',
		slotName: 'projectTypeName',
	},
	{
		title: '项目类别',
		minWidth: 80,
		dataIndex: 'projectCategoryName',
		slotName: 'projectCategoryName',
		tooltip: true,
	},
	{
		title: '所属院系（部）',
		minWidth: 140,
		dataIndex: 'departmentName',
		slotName: 'departmentName',
		tooltip: true,
	},
	{
		title: '起止时间',
		minWidth: 170,
		dataIndex: 'createTime',
		slotName: 'createTime',
		tooltip: true,
	},
	{
		title: '项目经费',
		minWidth: 70,
		dataIndex: 'projectFunding',
		slotName: 'projectFunding',
		tooltip: true,
	},
	{
		title: '项目级别',
		minWidth: 80,
		dataIndex: 'projectLevelName',
		slotName: 'projectLevelName',
		tooltip: true,
	},
	{
		title: '项目状态',
		minWidth: 110,
		dataIndex: 'statusName',
		slotName: 'statusName',
		tooltip: true,
	},
	{
		minWidth: 200,
		title: '操作',
		dataIndex: 'default',
		slotName: 'default',
	}
])

// 表头
const columns2 = ref([
	{
		title: '序号',
		width: 48,
		dataIndex: 'key',
		formatter: (_row: any, _column: any, _cellValue: any, index: number) => {
			return index + 1
		}
	},
	{
		title: '合同编号',
		dataIndex: 'projectCode',
		slotName: 'projectCode',
		minWidth: 100,
	},
	{
		title: '合同名称',
		minWidth: 330,
		dataIndex: 'projectName',
		slotName: 'projectName',
	},
	{
		title: '负责人',
		minWidth: 80,
		dataIndex: 'managerName',
		slotName: 'managerName',
		tooltip: true,
	},
	{
		title: '团队成员',
		minWidth: 120,
		dataIndex: 'teamMember',
		slotName: 'teamMember',
		tooltip: true,
	},
	{
		title: '合同类别',
		minWidth: 80,
		dataIndex: 'projectCategoryName',
		slotName: 'projectCategoryName',
		tooltip: true,
	},
	{
		title: '所属院系（部）',
		minWidth: 140,
		dataIndex: 'departmentName',
		slotName: 'departmentName',
		tooltip: true,
	},
	{
		title: '起止时间',
		minWidth: 170,
		dataIndex: 'createTime',
		slotName: 'createTime',
		tooltip: true,
	},
	{
		title: '项目经费',
		minWidth: 80,
		dataIndex: 'projectFunding',
		slotName: 'projectFunding',
		tooltip: true,
	},
	{
		title: '项目状态',
		minWidth: 110,
		dataIndex: 'statusName',
		slotName: 'statusName',
		tooltip: true,
	},
	{
		minWidth: 200,
		title: '操作',
		dataIndex: 'default',
		slotName: 'default',
	}
])

// 搜索条件组件配置数据
const conditionComponents = ref([
	{
		type: 1,
		key: 'projectType',
		value: '单选框',
		cValue: projectType.value,
		placeholder: '项目分类',
		config: {
			options: projectTypeList
		}
	},
	{
		type: 1,
		key: 'projectCategory',
		value: '',
		placeholder: '项目类别',
		config: {
			options: typeList
		}
	},
	{
		type: 1,
		key: 'department',
		value: '',
		placeholder: '所属院系（部）',
		config: {
			options: departmentList
		}
	},
	{
		type: 1,
		key: 'projectLevel',
		value: '',
		placeholder: '项目级别',
		config: {
			options: projectLevelList
		}
	},
	{
		type: 2,
		key: 'createTime',
		value: '',
		width: 280,
		placeholder: '起止时间',
		config: {
			pickerOptions: {
				shortcuts: [{
					text: '最近一周',
					onClick(picker) {
						const end = new Date();
						const start = new Date();
						start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
						picker.$emit('pick', [start, end]);
					}
				}, {
					text: '最近一个月',
					onClick(picker) {
						const end = new Date();
						const start = new Date();
						start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
						picker.$emit('pick', [start, end]);
					}
				}, {
					text: '最近三个月',
					onClick(picker) {
						const end = new Date();
						const start = new Date();
						start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
						picker.$emit('pick', [start, end]);
					}
				}]
			}
		}
	},
	{
		type: 1,
		key: 'status',
		value: '单选框',
		cValue: status.value,
		placeholder: '项目状态',
		config: {
			options: projectStatusList,
			multiple: true
		}
	},
	{
		type: 0,
		value: '',
		key: 'managerName',
		placeholder: '请输入负责人',
	},
	{
		type: 0,
		value: '',
		key: 'projectName',
		placeholder: '请输入项目名称',
	},
])
// 搜索条件组件配置数据
const conditionComponents2 = ref([
	{
		type: 1,
		key: 'status',
		value: '单选框',
		cValue: status.value,
		placeholder: '项目状态',
		config: {
			options: projectStatusList,
			multiple: true
		}
	},
	{
		type: 1,
		key: 'projectCategory',
		value: '',
		placeholder: '合同类别',
		config: {
			options: typeList
		}
	},
	{
		type: 1,
		key: 'department',
		value: '',
		placeholder: '所属院系（部）',
		config: {
			options: departmentList
		}
	},
	{
		type: 2,
		key: 'createTime',
		value: '',
		width: 280,
		placeholder: '起止时间',
		config: {
			pickerOptions: {
				shortcuts: [{
					text: '最近一周',
					onClick(picker) {
						const end = new Date();
						const start = new Date();
						start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
						picker.$emit('pick', [start, end]);
					}
				}, {
					text: '最近一个月',
					onClick(picker) {
						const end = new Date();
						const start = new Date();
						start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
						picker.$emit('pick', [start, end]);
					}
				}, {
					text: '最近三个月',
					onClick(picker) {
						const end = new Date();
						const start = new Date();
						start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
						picker.$emit('pick', [start, end]);
					}
				}]
			}
		}
	},

	{
		type: 0,
		value: '',
		key: 'managerName',
		placeholder: '请输入负责人',
	},
	{
		type: 0,
		value: '',
		key: 'projectName',
		placeholder: '请输入项目名称',
	},
])

const { proxy } = getCurrentInstance();

const configList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0);
const title = computed(() => {
	switch (projectNature.value) {
		case projectNatureEnum.projectNatureSchool:
			return '校级项目列表'
		case projectNatureEnum.projectNatureHorizontal:
			return '横向项目列表'
		default:
			return '纵向项目列表'
	}
})
const checkFlag = ref(true) // 中检提交预警
const checkNumber = ref(1) // 中检开始后
const checkUnit = ref(1) // 中检开始后
const conclusionFlag = ref(true) // 结项预警
const conclusionNumber = ref(1) // 结项预警前
const conclusionUnit = ref(1) // 结项预警单位
const alertId = ref('') // 预警id

// 项目列表
const { run: getList } = useRequest(getProjectPageApi, {
	manual: true,
	onSuccess: (response) => {
		configList.value = response.content
		total.value = response.totalElements;
		loading.value = false;
	}
})

// 发起中检
const { run: getAlertDetail } = useRequest(getAlertDetailApi, {
	manual: true,
	onSuccess: (response: ProjectWarmingBaseDetailVO) => {
		if (!response) return
		checkFlag.value = response.checkFlag
		checkNumber.value = response.checkNumber
		checkUnit.value = response.checkUnit
		conclusionFlag.value = response.conclusionFlag
		conclusionNumber.value = response.conclusionNumber
		conclusionUnit.value = response.conclusionUnit
		alertId.value = response.id
	}
})

// 项目预警设置
const { run: warningBaseCreate } = useRequest(warningBaseCreateApi, {
	manual: true,
	onSuccess: (response: BaseSuccessRespDTO) => {
		if (response.isSuccess) {
			ElMessage({
				message: '设置成功',
				type: 'success',
			})
			getAlertDetail({ projectNature: projectNature.value })
			open.value = false
		}
	}
})
// 项目预警设置
const { run: warningBaseUpdate } = useRequest(warningBaseUpdateApi, {
	manual: true,
	onSuccess: (response: BaseSuccessRespDTO) => {
		if (response.isSuccess) {
			ElMessage({
				message: '修改成功',
				type: 'success',
			})
			getAlertDetail({ projectNature: projectNature.value })
			open.value = false
		}
	}
})

// 导出参数
const downloadParameters = ref({
	projectNature: projectNature.value,
	idList: []
})

const data = reactive({
	form: {},
	queryParams: {
		page: 1,
		size: 20,
		projectNature: projectNature.value,
		status: status.value,
		projectType: projectType.value
	},
	rules: {
		configName: [{ required: true, message: "参数名称不能为空", trigger: "blur" }],
		configKey: [{ required: true, message: "参数键名不能为空", trigger: "blur" }],
		configValue: [{ required: true, message: "参数键值不能为空", trigger: "blur" }]
	}
});

const { queryParams, form } = toRefs(data);

/* 导出列表数据 */
const { runAsync: exportFile } = useRequest(exportProjectListApi, {
	// false 为自动执行
	manual: true,
	// 请求成功
	onSuccess: () => {
	},
	// 请求失败
	onError: () => {
	},
})

const refreshTableData = (params) => {
	loading.value = true
	queryParams.value.page = params.page;
	queryParams.value.size = params.size;
	getList({ ...queryParams.value, });
	setTimeout(() => {
		loading.value = false
	}, 1000)
}

const setAlert = () => {
	open.value = true
}

const linkToCreate = (type) => {
	console.log('跳转页面》')
	router.push({
		path: '/project/manage/notices',
		query: {
			projectNature: type
		}
	})
}

const onSelectRows = (ids) => {
	console.log('选中的ids》', ids)
	selectRowList.value = ids
}

// 导出
const exportListData = async (params) => {
	downloadParameters.value.idList = params
	const res = await exportFile({
		...downloadParameters.value,
		...searchBarRef.value.params,
		...queryParams.value
	})
	downloadFile(res)
}

/** 取消按钮 */
function cancel() {
	open.value = false;
	reset();
}

/** 表单重置 */
function reset() {
	form.value = {
		configId: undefined,
		configName: undefined,
		configKey: undefined,
		configValue: undefined,
		configType: "Y",
		remark: undefined
	};
	proxy.resetForm("configRef");
}

/** 提交按钮 */
function submitForm() {
	if (conclusionFlag.value && conclusionNumber.value === '') {
		return ElMessage.error('请填写完整')
	}

	let params = {
		conclusionFlag: conclusionFlag.value,
		conclusionNumber: conclusionFlag.value ? conclusionNumber.value : undefined,
		conclusionUnit: conclusionFlag.value ? conclusionUnit.value : undefined
	}
	if (projectNature.value !== projectNatureEnum.projectNatureHorizontal) {
		if (checkFlag.value && checkNumber.value === '') {
			return ElMessage.error('请填写完整')
		}
		params = {
			...params,
			checkFlag: checkFlag.value,
			checkNumber: checkFlag.value ? checkNumber.value : undefined,
			checkUnit: checkFlag.value ? checkUnit.value : undefined,
		}
	}
	if (!alertId.value) {
		warningBaseCreate({ ...params, projectNature: projectNature.value })
	} else {
		warningBaseUpdate({ ...params, projectNature: projectNature.value, id: alertId.value || undefined })
	}
}

// 搜索
function onSearch(params) {
	console.log('搜索参数》', params)
	const [approvalTime, conclusionTime] = params?.createTime || []
	console.log(queryParams, 'queryParams');
	queryParams.value = Object.assign(queryParams.value, params)
	getList({ ...params, ...queryParams.value, createTime: undefined, approvalTime, conclusionTime })
}

getList({ ...queryParams.value });
getDicList({})
getAlertDetail({ projectNature: projectNature.value })
getDepartmentList()

</script>

<style scoped lang="scss">
:deep(.el-input-number .el-input__inner) {
	text-align: left;
}

.home {
	blockquote {
		padding: 10px 20px;
		margin: 0 0 20px;
		font-size: 17.5px;
		border-left: 5px solid #eee;
	}

	hr {
		margin-top: 20px;
		margin-bottom: 20px;
		border: 0;
		border-top: 1px solid #eee;
	}

	.col-item {
		margin-bottom: 20px;
	}

	ul {
		padding: 0;
		margin: 0;
	}

	font-family: "open sans",
	"Helvetica Neue",
	Helvetica,
	Arial,
	sans-serif;
	font-size: 13px;
	color: #676a6c;
	overflow-x: hidden;

	ul {
		list-style-type: none;
	}

	h4 {
		margin-top: 0px;
	}

	h2 {
		margin-top: 10px;
		font-size: 26px;
		font-weight: 100;
	}

	p {
		margin-top: 10px;

		b {
			font-weight: 700;
		}
	}

	.update-log {
		ol {
			display: block;
			list-style-type: decimal;
			margin-block-start: 1em;
			margin-block-end: 1em;
			margin-inline-start: 0;
			margin-inline-end: 0;
			padding-inline-start: 40px;
		}
	}
}
</style>